﻿using System;

/* 
 * 创建人：Kewin
 * 
 * 时间：2010.6-2010.9
 * 
 * 说明：
 * 
 * 
 * 修改说明：
 * 
 * 
 */


namespace ConsoleTest.ChapterTen
{
    /// <summary>
    /// 委托
    /// </summary>
    public class Delegate
    {
        /*委托基本概念
         * C#委托相当于C++中的函数指针，但是C#的委托语法更加清晰易用，且可以同时引用多个方法（静态或非静态）
         * 
         * 委托调用其引用方法的顺序与添加到委托对象中的顺序相同
         * 如果方法具有返回值，那么返回值为最有一个方法的返回值
         */

        /*编译器委托类推测功能
         * 
         * 为什么可以直接将与委托签名式相同的方法直接赋给委托对象
         * 这是因为C#编译器会隐式的调用委托类的构造函数创建委托对象，可以通过查看il代码
         */

        public delegate void InPriceDelegate(int i);
        /// <summary>
        /// 
        /// </summary>
        public static void DelegateList()
        {
            Article a = new Article(100);
            Article b = new Article(103);
            Article c = new Article(107);

            InPriceDelegate deleg = a.InPrice;
            InPriceDelegate deleg1 = b.InPrice;
            deleg1 += c.InPrice;
            deleg += deleg1;//将一个委托对象添加到另外一个委托对象；
            //如果添加的委托对象包含多个方法的引用，那么这些方法的引用会被添加到引用列表的尾部
            deleg(10);
            System.Console.WriteLine("deleg has {0} numbers of Delegate Instance",deleg.GetInvocationList().Length);
            System.Console.WriteLine("-------------------------");

            InPriceDelegate deleg2 = a.InPrice;
            deleg2 += c.InPrice;
            deleg -= deleg2;//删除方法引用时如果删除的引用列表没有出现在目标委托对象的引用列表中删除失败
            deleg(10);
            System.Console.WriteLine("deleg has {0} numbers of Delegate Instance" , deleg.GetInvocationList().Length);
            System.Console.WriteLine("-------------------------");

            InPriceDelegate deleg3 = a.InPrice;
            deleg3 += b.InPrice;
            deleg -= deleg3;
            deleg(10);
            System.Console.WriteLine("deleg has {0} numbers of Delegate Instance" ,deleg.GetInvocationList().Length);
            System.Console.WriteLine("-------------------------");
        }
        
    }


    /// <summary>
    /// 
    /// </summary>
    public class Article
    {
        public int m_price = 0;//结构体的字段在声明时就不能进行初始化
        public Article(int price) { m_price = price; }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="i"></param>
        public void InPrice(int i)
        {
            System.Console.WriteLine(this.ToString()+" price before add {0}",m_price);
            m_price += i;
            System.Console.WriteLine(this.ToString() + " price after  add {0}", m_price);
        }
    }
}